package com.cssw.fyzb.busi.service.live;

import com.alibaba.fastjson.JSON;
import com.cssw.fyzb.busi.cache.Cache;
import com.cssw.fyzb.busi.cache.CacheKeys;
import com.cssw.fyzb.busi.config.EventClient;
import com.cssw.fyzb.busi.config.TpsClient;
import com.cssw.fyzb.core.model.vo.live.LatestGiftVo;
import com.cssw.fyzb.core.model.vo.live.LivePkVo;
import com.cssw.fyzb.busi.util.BizUtil;
import com.cssw.fyzb.busi.util.Bizs;
import com.cssw.fyzb.busi.util.UuidUtil;
import com.cssw.fyzb.core.dao.acct.AcctDao;
import com.cssw.fyzb.core.dao.live.GiftDao;
import com.cssw.fyzb.core.eao.acct.AcctLogEao;
import com.cssw.fyzb.core.mao.live.LivePkMao;
import com.cssw.fyzb.core.mao.live.UserLiveMao;
import com.cssw.fyzb.core.mao.user.UserMao;
import com.cssw.fyzb.core.model.dodb.*;
import com.cssw.fyzb.core.model.mos.UserMo;
import com.ydn.appserver.Request;
import com.ydn.dbframe.plugin.activerecord.Db;
import com.ydn.dbframe.plugin.activerecord.Page;
import com.ydn.dbframe.plugin.activerecord.Record;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author wondream
 */
@Service
public class GiftServiceImpl implements GiftService {

    @Autowired
    private GiftDao giftDao;

    @Autowired
    private UserMao userMao;

    @Autowired
    private AcctDao acctDao;

    @Autowired
    private UserLiveMao userLiveMao;

    @Autowired
    private LivePkMao livePkMao;

    @Autowired
    private TpsClient tpsClient;

    @Autowired
    private AcctLogEao acctLogEao;

    @Autowired
    private EventClient eventClient;

    private static final Integer RANK_SIZE = 3;

    /**
     * 查询单个礼物配置
     *
     * @return
     */
    @Override
    public CmfGift queryById(Long giftId) {
        return Cache.get(CacheKeys.giftKey(giftId), () -> giftDao.queryById(giftId));
    }

    /**
     * 获取礼物列表
     *
     * @return
     */
    public Page<CmfGift> listGift(int pageNumber, int pageSize) {
        return giftDao.listGift(pageNumber, pageSize, new HashMap());
    }

    /**
     * 赠送礼物
     *
     * @param fromUserId
     * @param toUserId
     * @param liveId
     * @param giftId
     * @return
     */
    public void sendGift(Long fromUserId, Long toUserId, Long liveId, Long giftId) {
        CmfGift cmfGift = queryById(giftId);
        if (cmfGift == null) {
            BizUtil.exception("赠送失败");
        }

//        BigDecimal needCoin = cmfGift.getNeedCoin();
//        BigDecimal giftYCoin = cmfGift.getGiftYCoin();

        Acct acct = acctDao.queryFAcct(fromUserId);
//        if (acct.getBalanceFee().compareTo(needCoin) < 0) {
//            BizUtil.exception(Bizs.ERROR_BALANCE_LESS);
//        }
        UserMo fromUser = userMao.findByUserId(fromUserId);
        UserMo toUser = userMao.findByUserId(toUserId);

        //开始赠送礼物事务
        Db.tx(() -> {
            // 添加礼物日志
//            Long logId = giftDao.addSendGiftLog(fromUserId, toUserId, liveId, giftId, needCoin, giftYCoin);
//
//
//            //记录本场直播店礼物记录
//            userLiveMao.incReward(liveId, fromUserId, giftYCoin.intValue());
//
//            // 赠送礼物日志
//            String sendTradeName = cmfGift.getGiftName() + "-" + "赠送给" + toUser.getNickName();
//            giftDao.addGiftLog(fromUserId, giftId, "2", 1, logId.toString(), AcctTradeType.SEND_GIFT, sendTradeName);
//
//            // 收到礼物日志
//            String receTradeName = cmfGift.getGiftName() + "-" + "来自" + fromUser.getNickName();
//            giftDao.addGiftLog(toUserId, giftId, "1", 1, logId.toString(), AcctTradeType.RECEIVE_GIFT, receTradeName);
//
//            // 减少余额
//            acctDao.minusBalance(fromUserId, AcctType.ACCT_TYPE_F, needCoin, logId.toString(), AcctTradeType.SEND_GIFT, BusiType.SEND_GIFT);
//
//            //记录es日志
//            acctLogEao.save(UuidUtil.get(), acct.getAcctId(), fromUserId, AcctType.ACCT_TYPE_F, needCoin,
//                    Acct.FEE_IN_DE_MINUS, logId.toString(), AcctTradeType.SEND_GIFT, sendTradeName,
//                    BusiType.SEND_GIFT, new Date());
//
//            // 增加余额
//            acctDao.addBalance(toUserId, AcctType.ACCT_TYPE_Y, giftYCoin, logId.toString(), AcctTradeType.RECEIVE_GIFT, BusiType.SEND_GIFT);
//
//            Acct toAcct = acctDao.queryYAcct(toUserId);
//            //记录es日志
//            acctLogEao.save(UuidUtil.get(), toAcct.getAcctId(), toUserId, AcctType.ACCT_TYPE_Y, giftYCoin,
//                    Acct.FEE_IN_DE_ADD, logId.toString(), AcctTradeType.RECEIVE_GIFT, receTradeName,
//                    BusiType.SEND_GIFT, new Date());

            if (userLiveMao.existsGift(liveId, giftId)){
                userLiveMao.incGift(liveId, giftId);
            } else {
                userLiveMao.saveGift(liveId, giftId);
            }

            return true;
        });

        // 通知发送礼物
        notifySendGift(liveId, fromUser, cmfGift);

        //异步重算
        Map<String, Object> param = new HashMap<>();
        param.put("liveId", liveId);
        eventClient.fireEvent("reRank", JSON.toJSONString(param));

        doPk(liveId, fromUser, cmfGift);

    }

    private void doPk(Long liveId, UserMo user, CmfGift cmfGift) {
        LivePkVo pkVo = Cache.get(CacheKeys.pkingKey(liveId));

        // 不在pk中
        if (pkVo == null || System.currentTimeMillis() > pkVo.getExpire()) {
            Cache.remove(CacheKeys.pkingKey(liveId));
            return;
        }

        // 在pk中
        incReward(pkVo.getPkId(), liveId, user, cmfGift);

        Map<String, Object> param = new HashMap<>();
        param.put("liveId", liveId);
        param.put("pkId", pkVo.getPkId());
        eventClient.fireEvent("rePkRank", JSON.toJSONString(param));
    }

    private void sendGroupCustomMsg(Long liveId, Map<String, Object> data){
        Request request = new Request("SendGroupCustomMsg");
        request.setParameter("groupId", liveId);
        request.setParameter("data", JSON.toJSONString(data));

        tpsClient.send(request);
    }

    private void incReward(Long pkId, Long liveId, UserMo user, CmfGift cmfGift) {
        if (!livePkMao.exists(liveId, pkId, user.getUserId())) {
            livePkMao.enterPk(liveId, pkId, user.getUserId());
        }
//        livePkMao.incReward(liveId, pkId, user.getUserId(), cmfGift.getGiftYCoin().intValue());
    }


    //添加礼物日志
    @Override
    public Long addSendGiftLog(Long fromUserId, Long toUserId, Long liveId, Long giftId, BigDecimal fCoin, BigDecimal yCoin) {
        return giftDao.addSendGiftLog(fromUserId, toUserId, liveId, giftId, fCoin, yCoin);
    }

    @Override
    public Long addGiftLog(Long userId, Long giftId, String type, Integer nums, String tradeId, String tradeType, String tradeName) {
        return giftDao.addGiftLog(userId, giftId, type, nums, tradeId, tradeType, tradeName);
    }

    @Override
    public Page<GiftLog> listGiftLog(Long userId, Integer pageNumber, Integer pageSize) {
        return giftDao.listGiftLog(userId, pageNumber, pageSize);
    }

    /**
     * 主播收到礼物列表
     *
     * @return
     */
    public Page listReceivedGift(Long userId, Integer pageNumber, Integer pageSize) {
        return giftDao.listReceivedGift(userId, pageNumber, pageSize);
    }

    /**
     * 用户赠送礼物列表
     *
     * @return
     */
    public Page listSendGift(Long userId, Integer pageNumber, Integer pageSize) {
        return giftDao.listSendGift(userId, pageNumber, pageSize);
    }

    /**
     * 主播收到礼物统计(根据礼物id)
     *
     * @return
     */
    public Page<Record> receivedGiftStatistics(Long userId, Integer pageNumber, Integer pageSize) {
        return giftDao.receivedGiftStatistics(userId, pageNumber, pageSize);
    }


    // SECTION : INNER HELPER

    // 通知发送礼物

    private void notifySendGift(Long liveId, UserMo user, CmfGift gift) {

        // 获取当前 礼物状态
//        LatestGiftVo latestGift = getLatestGift(liveId, user.getUserId(), gift.getGiftId());
//
//        // 通知im
//        Map<String, Object> data = new HashMap<>();
//        data.put("cmd", "gift");
//        data.put("nickName", user.getNickName());
//        data.put("avatar", user.getAvatar());
//        data.put("giftName", gift.getGiftName());
//        data.put("giftPic", gift.getImage());
//        data.put("amount", latestGift.getAmount());
//
//        sendGroupCustomMsg(liveId, data);

    }

    private LatestGiftVo getLatestGift(Long liveId, Long userId, Long giftId) {
        Long now = System.currentTimeMillis();

        // 判断连击
        LatestGiftVo gift = Cache.get(CacheKeys.latestGiftKey(liveId, userId));
        LatestGiftVo current = new LatestGiftVo();
        current.setGift(giftId);
        current.setTime(now);
        if (gift == null || (now - gift.getTime()) > 3000) {
            // 不是连击
            current.setAmount(1);
        } else {
            // 是连击
            current.setAmount(gift.getAmount() + 1);
        }

        // 当前状态放入缓存
        Cache.put(CacheKeys.latestGiftKey(liveId, userId), current);

        // 返回当前状态
        return current;
    }

}
